## Warning in scpcaTools::add_miQC(filtered_sce): prob_compromised was already
## calculated and will be replaced.
## Warning in miQC::mixtureModel(sce): Unable to identify two distributions. Use plotMetrics function
## to confirm assumptions of miQC are met.
## Warning in miQC::mixtureModel(sce): Unable to identify two distributions. Use plotMetrics function
## to confirm assumptions of miQC are met.
## Warning in miQC::mixtureModel(sce): Unable to identify two distributions. Use plotMetrics function
## to confirm assumptions of miQC are met.
RNA-seq Experiment Summary
Cell Statistics
|
|
|
|
Method used to filter empty droplets
|
emptyDropsCellRanger
|
|
Number of cells post filtering empty droplets
|
5,909
|
|
Percent of reads in cells
|
88.4%
|
|
Median UMI count per cell
|
581
|
|
Median genes detected per cell
|
492
|
|
Median percent reads mitochondrial
|
6%
|
|
Method used to filter low quality cells
|
Minimum_gene_cutoff
|
|
Cells after filtering low quality cells
|
5,874
|
|
Normalization method
|
deconvolution
|
|
Minimum genes per cell cutoff
|
200
|
Knee Plot

The total UMI count of each droplet (barcode) plotted against the rank of that droplet allows visualization of the distribution of sequencing depth across droplets. The droplets that are expected to contain cells were identified with DropletUtils::emptyDropsCellRanger(), unless otherwise specified in the Cell Statistics table, which uses both the total UMI counts and expressed gene content (adapted from Lun et al. 2019). As the boundary between droplets passing and failing this filter is not solely dependent on total UMI count, some regions contain droplets in both categories. The color in this plot indicates the percentage of droplets in a region passing the filter.
Cell Read Metrics

The above plot of cell metrics includes only droplets which have passed the emptyDropsCellRanger() filter. The plot will usually display a strong (but curved) relationship between the total UMI count and the number of genes detected. Cells with low UMI counts and high mitochondrial percentages may require further filtering.
miQC Model Diagnostics

We calculate the probability that a cell is compromised due to degradation or rupture using miQC (Hippen et al. 2021). This relies on fitting a mixture model using the number of genes expressed by a cell and the percentage of mitochondrial reads. The expected plot will show a characteristic triangular shape and two model fit lines. Cells with low numbers of genes expressed may have both low and high mitochondrial percentage, but cells with many genes tend to have a low mitochondrial percentage. Compromised cells are likely to have a fewer genes detected and higher percentage of mitochondrial reads.
If the model has failed to fit properly, the pattern of cells may differ, and there may not be model fit lines. This can be the result of a low-quality library or may occur if there is no mitochondrial content, as in the case of a high-quality single-nucleus sample. In such situations, the calculated probability of compromise may not be valid (see miQC vignette for more details).
Removing low quality cells
The below plot highlights cells that were removed prior to normalization and dimensionality reduction. Cells that should be removed based on RNA counts are those that are identified to be low quality cells, such as cells with high probability of being compromised. The method of filtering is indicated above the plot as either miQC or Minimum gene cutoff. If miQC, cells below the specified probability compromised cutoff and above the minimum number of unique genes identified are kept for downstream analyses. If only a Minimum gene cutoff is used, then miQC is not used and only those cells that pass the minimum number of unique genes identified threshold are retained. The dotted vertical line indicates the minimum gene cutoff used for filtering.

The raw counts from all cells that remain after filtering low quality cells (RNA only) are then normalized prior to selection of highly variable genes and dimensionality reduction.
Dimensionality Reduction
The below plot shows the UMAP (Uniform Manifold Approximation and Projection) embeddings for each cell, coloring each cell by the total number of genes detected per cell.

Expression of highly variable genes
The plots below show the same UMAP embeddings, coloring each cell by the expression level of the labeled gene. The genes chosen for plotting are the 12 most variable genes identified in the library. Gene symbols are used when available to label the UMAP plots. If gene symbols are not available, the Ensembl id will be shown.

Cell type Annotation Summary
The plots and tables included here detail the results from performing cell type annotation.
This library contains the following cell type annotations:
For additional information about cell typing, including methods used for cell typing, information about reference sources, comparisons among cell type annotation methods, and diagnostic plots, please refer to the supplementary cell type QC report.
Statistics
SingleR cell type annotations
In this table, cells labeled “Unknown cell type” are those which
SingleR pruned due to low-quality assignments. In the processed result files, these cells are labeled
NA.
|
Annotated cell type
|
Number of cells
|
Percent of cells
|
|
CD4-positive, alpha-beta T cell
|
1551
|
26.4%
|
|
central memory CD8-positive, alpha-beta T cell
|
972
|
16.55%
|
|
common lymphoid progenitor
|
540
|
9.19%
|
|
central memory CD4-positive, alpha-beta T cell
|
536
|
9.12%
|
|
regulatory T cell
|
486
|
8.27%
|
|
effector memory CD8-positive, alpha-beta T cell
|
370
|
6.3%
|
|
dendritic cell
|
250
|
4.26%
|
|
CD8-positive, alpha-beta T cell
|
203
|
3.46%
|
|
plasma cell
|
161
|
2.74%
|
|
natural killer cell
|
157
|
2.67%
|
|
effector memory CD4-positive, alpha-beta T cell
|
156
|
2.66%
|
|
megakaryocyte-erythroid progenitor cell
|
120
|
2.04%
|
|
granulocyte monocyte progenitor cell
|
102
|
1.74%
|
|
hematopoietic stem cell
|
91
|
1.55%
|
|
hematopoietic multipotent progenitor cell
|
62
|
1.06%
|
|
erythrocyte
|
44
|
0.75%
|
|
neuron
|
29
|
0.49%
|
|
megakaryocyte
|
7
|
0.12%
|
|
class switched memory B cell
|
6
|
0.1%
|
|
keratinocyte
|
6
|
0.1%
|
|
melanocyte
|
5
|
0.09%
|
|
memory B cell
|
3
|
0.05%
|
|
naive B cell
|
3
|
0.05%
|
|
epithelial cell
|
2
|
0.03%
|
|
inflammatory macrophage
|
2
|
0.03%
|
|
microvascular endothelial cell
|
2
|
0.03%
|
|
monocyte
|
2
|
0.03%
|
|
common myeloid progenitor
|
1
|
0.02%
|
|
fat cell
|
1
|
0.02%
|
|
macrophage
|
1
|
0.02%
|
|
Unknown cell type
|
3
|
0.05%
|
CellAssign cell type annotations
In this table, cells labeled “Unknown cell type” are those which
CellAssign could not confidently assign to a label in the reference list. In the processed result files, these cells are labeled
"other".
|
Annotated cell type
|
Number of cells
|
Percent of cells
|
|
T helper cells
|
56
|
0.95%
|
|
T cells
|
42
|
0.72%
|
|
Nuocytes
|
12
|
0.2%
|
|
Microglia
|
9
|
0.15%
|
|
T regulatory cells
|
9
|
0.15%
|
|
Oligodendrocyte progenitor cells
|
6
|
0.1%
|
|
Monocytes
|
2
|
0.03%
|
|
Dendritic cells
|
1
|
0.02%
|
|
Endothelial cells (aorta)
|
1
|
0.02%
|
|
GABAergic neurons
|
1
|
0.02%
|
|
Gamma delta T cells
|
1
|
0.02%
|
|
Macrophages
|
1
|
0.02%
|
|
Myeloid-derived suppressor cells
|
1
|
0.02%
|
|
Natural killer T cells
|
1
|
0.02%
|
|
Neural stem/precursor cells
|
1
|
0.02%
|
|
NK cells
|
1
|
0.02%
|
|
Trophoblast cells
|
1
|
0.02%
|
|
Unknown cell type
|
5728
|
97.51%
|
UMAPs
In this section, we show UMAPs colored by clusters. Clusters were calculated using the graph-based Louvain algorithm with Jaccard weighting.

Next, we show UMAPs colored by cell types. For each cell typing method, we show a separate faceted UMAP. In each panel, cells that were assigned the given cell type label are colored, while all other cells are in grey.
For legibility, only the seven most common cell types are shown. All other cell types are grouped together and labeled “All remaining cell types” (not to be confused with “Unknown cell type” which represents cells that could not be classified).


Session Info
R session information
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.4.1 (2024-06-14)
## os Ubuntu 22.04.4 LTS
## system x86_64, linux-gnu
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz Etc/UTC
## date 2024-08-02
## pandoc 2.9.2.1 @ /usr/bin/ (via rmarkdown)
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## abind 1.4-5 2016-07-21 [1] RSPM (R 4.4.0)
## beachmat 2.20.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## beeswarm 0.4.0 2021-06-01 [1] RSPM (R 4.4.0)
## Biobase * 2.64.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## BiocGenerics * 0.50.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## BiocNeighbors 1.22.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## BiocParallel 1.38.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## BiocSingular 1.20.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## bluster 1.14.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## bslib 0.7.0 2024-03-29 [1] RSPM (R 4.4.0)
## cachem 1.1.0 2024-05-16 [1] RSPM (R 4.4.0)
## cli 3.6.3 2024-06-21 [1] RSPM (R 4.4.0)
## cluster 2.1.6 2023-12-01 [2] CRAN (R 4.4.1)
## codetools 0.2-20 2024-03-31 [2] CRAN (R 4.4.1)
## colorspace 2.1-0 2023-01-23 [1] RSPM (R 4.4.0)
## crayon 1.5.3 2024-06-20 [1] RSPM (R 4.4.0)
## DelayedArray 0.30.1 2024-05-07 [1] Bioconductor 3.19 (R 4.4.1)
## DelayedMatrixStats 1.26.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## digest 0.6.36 2024-06-23 [1] RSPM (R 4.4.0)
## dplyr * 1.1.4 2023-11-17 [1] RSPM (R 4.4.0)
## dqrng 0.4.1 2024-05-28 [1] RSPM (R 4.4.0)
## edgeR 4.2.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## evaluate 0.24.0 2024-06-10 [1] RSPM (R 4.4.0)
## fansi 1.0.6 2023-12-08 [1] RSPM (R 4.4.0)
## farver 2.1.2 2024-05-13 [1] RSPM (R 4.4.0)
## fastmap 1.2.0 2024-05-15 [1] RSPM (R 4.4.0)
## flexmix 2.3-19 2023-03-16 [1] RSPM (R 4.4.0)
## forcats 1.0.0 2023-01-29 [1] RSPM (R 4.4.0)
## generics 0.1.3 2022-07-05 [1] RSPM (R 4.4.0)
## GenomeInfoDb * 1.40.1 2024-05-24 [1] Bioconductor 3.19 (R 4.4.1)
## GenomeInfoDbData 1.2.12 2024-06-25 [1] Bioconductor
## GenomicRanges * 1.56.1 2024-06-12 [1] Bioconductor 3.19 (R 4.4.1)
## getopt 1.20.4 2023-10-01 [1] RSPM (R 4.4.0)
## ggbeeswarm 0.7.2 2023-04-29 [1] RSPM (R 4.4.0)
## ggplot2 * 3.5.1 2024-04-23 [1] RSPM (R 4.4.0)
## ggrepel 0.9.5 2024-01-10 [1] RSPM (R 4.4.0)
## glue 1.7.0 2024-01-09 [1] RSPM (R 4.4.0)
## gridExtra 2.3 2017-09-09 [1] RSPM (R 4.4.0)
## gtable 0.3.5 2024-04-22 [1] RSPM (R 4.4.0)
## highr 0.11 2024-05-26 [1] RSPM (R 4.4.0)
## hms 1.1.3 2023-03-21 [1] RSPM (R 4.4.0)
## htmltools 0.5.8.1 2024-04-04 [1] RSPM (R 4.4.0)
## httr 1.4.7 2023-08-15 [1] RSPM (R 4.4.0)
## igraph 2.0.3 2024-03-13 [1] RSPM (R 4.4.0)
## IRanges * 2.38.1 2024-07-03 [1] Bioconductor 3.19 (R 4.4.1)
## irlba 2.3.5.1 2022-10-03 [1] RSPM (R 4.4.0)
## jquerylib 0.1.4 2021-04-26 [1] RSPM (R 4.4.0)
## jsonlite 1.8.8 2023-12-04 [1] RSPM (R 4.4.0)
## kableExtra 1.4.0 2024-01-24 [1] RSPM (R 4.4.0)
## knitr 1.48 2024-07-07 [1] RSPM (R 4.4.0)
## labeling 0.4.3 2023-08-29 [1] RSPM (R 4.4.0)
## lattice 0.22-6 2024-03-20 [2] CRAN (R 4.4.1)
## lifecycle 1.0.4 2023-11-07 [1] RSPM (R 4.4.0)
## limma 3.60.3 2024-06-16 [1] Bioconductor 3.19 (R 4.4.1)
## locfit 1.5-9.10 2024-06-24 [1] RSPM (R 4.4.0)
## lubridate 1.9.3 2023-09-27 [1] RSPM (R 4.4.0)
## magrittr 2.0.3 2022-03-30 [1] RSPM (R 4.4.0)
## Matrix 1.7-0 2024-04-26 [2] CRAN (R 4.4.1)
## MatrixGenerics * 1.16.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## matrixStats * 1.3.0 2024-04-11 [1] RSPM (R 4.4.0)
## metapod 1.12.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## miQC 1.12.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## modeltools 0.2-23 2020-03-05 [1] RSPM (R 4.4.0)
## munsell 0.5.1 2024-04-01 [1] RSPM (R 4.4.0)
## nnet 7.3-19 2023-05-03 [2] CRAN (R 4.4.1)
## optparse * 1.7.5 2024-04-16 [1] RSPM (R 4.4.0)
## pillar 1.9.0 2023-03-22 [1] RSPM (R 4.4.0)
## pkgconfig 2.0.3 2019-09-22 [1] RSPM (R 4.4.0)
## purrr 1.0.2 2023-08-10 [1] RSPM (R 4.4.0)
## R6 2.5.1 2021-08-19 [1] RSPM (R 4.4.0)
## RColorBrewer 1.1-3 2022-04-03 [1] RSPM (R 4.4.0)
## Rcpp 1.0.12 2024-01-09 [1] RSPM (R 4.4.0)
## readr 2.1.5 2024-01-10 [1] RSPM (R 4.4.0)
## rlang 1.1.4 2024-06-04 [1] RSPM (R 4.4.0)
## rmarkdown 2.27 2024-05-17 [1] RSPM (R 4.4.0)
## rstudioapi 0.16.0 2024-03-24 [1] RSPM (R 4.4.0)
## rsvd 1.0.5 2021-04-16 [1] RSPM (R 4.4.0)
## S4Arrays 1.4.1 2024-05-20 [1] Bioconductor 3.19 (R 4.4.1)
## S4Vectors * 0.42.1 2024-07-03 [1] Bioconductor 3.19 (R 4.4.1)
## sass 0.4.9 2024-03-15 [1] RSPM (R 4.4.0)
## ScaledMatrix 1.12.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## scales 1.3.0 2023-11-28 [1] RSPM (R 4.4.0)
## scater 1.32.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## scpcaTools 0.4.0 2024-07-08 [1] local
## scran 1.32.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## scuttle 1.14.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## sessioninfo 1.2.2 2021-12-06 [1] RSPM (R 4.4.0)
## SingleCellExperiment * 1.26.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## SparseArray 1.4.8 2024-05-24 [1] Bioconductor 3.19 (R 4.4.1)
## sparseMatrixStats 1.16.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## statmod 1.5.0 2023-01-06 [1] RSPM (R 4.4.0)
## stringi 1.8.4 2024-05-06 [1] RSPM (R 4.4.0)
## stringr 1.5.1 2023-11-14 [1] RSPM (R 4.4.0)
## SummarizedExperiment * 1.34.0 2024-05-01 [1] Bioconductor 3.19 (R 4.4.1)
## svglite 2.1.3 2023-12-08 [1] RSPM (R 4.4.0)
## systemfonts 1.1.0 2024-05-15 [1] RSPM (R 4.4.0)
## tibble 3.2.1 2023-03-20 [1] RSPM (R 4.4.0)
## tidyr 1.3.1 2024-01-24 [1] RSPM (R 4.4.0)
## tidyselect 1.2.1 2024-03-11 [1] RSPM (R 4.4.0)
## timechange 0.3.0 2024-01-18 [1] RSPM (R 4.4.0)
## tzdb 0.4.0 2023-05-12 [1] RSPM (R 4.4.0)
## UCSC.utils 1.0.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## utf8 1.2.4 2023-10-22 [1] RSPM (R 4.4.0)
## vctrs 0.6.5 2023-12-01 [1] RSPM (R 4.4.0)
## vipor 0.4.7 2023-12-18 [1] RSPM (R 4.4.0)
## viridis 0.6.5 2024-01-29 [1] RSPM (R 4.4.0)
## viridisLite 0.4.2 2023-05-02 [1] RSPM (R 4.4.0)
## withr 3.0.0 2024-01-16 [1] RSPM (R 4.4.0)
## xfun 0.45 2024-06-16 [1] RSPM (R 4.4.0)
## xml2 1.3.6 2023-12-04 [1] RSPM (R 4.4.0)
## XVector 0.44.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
## yaml 2.3.9 2024-07-05 [1] RSPM (R 4.4.0)
## zlibbioc 1.50.0 2024-04-30 [1] Bioconductor 3.19 (R 4.4.1)
##
## [1] /usr/local/lib/R/site-library
## [2] /usr/local/lib/R/library
##
## ──────────────────────────────────────────────────────────────────────────────
LS0tCnBhcmFtczoKICBsaWJyYXJ5OiBFeGFtcGxlCiAgdW5maWx0ZXJlZF9zY2U6ICFyIHNjcGNhVG9vbHM6OjpzaW1fc2NlKCkKICBmaWx0ZXJlZF9zY2U6IE5VTEwKICBwcm9jZXNzZWRfc2NlOiBOVUxMCiAgY2VsbHR5cGVfcmVwb3J0OiBOVUxMCiAgZGF0ZTogIXIgU3lzLkRhdGUoKQogIHNlZWQ6IE5VTEwKCnRpdGxlOiAiYHIgZ2x1ZTo6Z2x1ZSgnU2NQQ0EgUUMgcmVwb3J0IGZvciB7cGFyYW1zJGxpYnJhcnl9JylgIgphdXRob3I6ICJDaGlsZGhvb2QgQ2FuY2VyIERhdGEgTGFiIgpkYXRlOiAiYHIgcGFyYW1zJGRhdGVgIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgbWVzc2FnZSA9IEZBTFNFLCBlY2hvID0gRkFMU0V9CiMga25pdHIgb3B0aW9ucwprbml0cjo6b3B0c19jaHVuayRzZXQoCiAgZWNobyA9IEZBTFNFCikKCmxpYnJhcnkoU2luZ2xlQ2VsbEV4cGVyaW1lbnQpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoZ2dwbG90MikKCiMgU2V0IGRlZmF1bHQgZ2dwbG90IHRoZW1lCnRoZW1lX3NldCgKICB0aGVtZV9idygpICsKICAgIHRoZW1lKAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbihyZXAoMjAsIDQpKSwKICAgICAgc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gInRyYW5zcGFyZW50IikKICAgICkKKQoKIyBIZWxwZXIgZnVuY3Rpb24gdG8gY2hhbmdlIE5VTEwgLT4gIk4vQSIgaW4gYSBkYXRhIGZyYW1lCnJlZm9ybWF0X251bGxzIDwtIGZ1bmN0aW9uKGRmKSB7CiAgZGYgfD4gbXV0YXRlKAogICAgYWNyb3NzKGV2ZXJ5dGhpbmcoKSwKICAgICAgLmZucyA9IFwoeCkgaWZlbHNlKHggPT0gIk5VTEwiLCAiTi9BIiwgeCkKICAgICkKICApCn0KCiMgU2V0IHNlZWQKc2V0LnNlZWQocGFyYW1zJHNlZWQpCmBgYAoKCjwhLS0gc291cmNlIGZ1bmN0aW9ucyAtLT4gCmBgYHtyLCBjaGlsZD0ndXRpbHMvcmVwb3J0X2Z1bmN0aW9ucy5ybWQnfQpgYGAKCgpgYGB7ciBzY2Vfc2V0dXB9CiMgc2F2ZSBzb21lIHR5cGluZyBsYXRlcgpsaWJyYXJ5X2lkIDwtIHBhcmFtcyRsaWJyYXJ5CnVuZmlsdGVyZWRfc2NlIDwtIHBhcmFtcyR1bmZpbHRlcmVkX3NjZQpmaWx0ZXJlZF9zY2UgPC0gcGFyYW1zJGZpbHRlcmVkX3NjZQpwcm9jZXNzZWRfc2NlIDwtIHBhcmFtcyRwcm9jZXNzZWRfc2NlCgpoYXNfZmlsdGVyZWQgPC0gIWlzLm51bGwoZmlsdGVyZWRfc2NlKQpoYXNfcHJvY2Vzc2VkIDwtICFpcy5udWxsKHByb2Nlc3NlZF9zY2UpCgojIGlmIHRoZXJlIGlzIG5vIGZpbHRlcmVkIHNjZSwgdXNlIHRoZSB1bmZpbHRlcmVkIGZvciBib3RoCmlmICghaGFzX2ZpbHRlcmVkKSB7CiAgZmlsdGVyZWRfc2NlIDwtIHVuZmlsdGVyZWRfc2NlCn0KCiMgZ3JhYiBzYW1wbGUgaWQgZnJvbSBmaWx0ZXJlZCBzY2UsIGlmIG1pc3Npbmcgc2V0IHNhbXBsZSBpZCB0byBOQQppZiAoaXMubnVsbChtZXRhZGF0YShmaWx0ZXJlZF9zY2UpJHNhbXBsZV9pZCkpIHsKICBzYW1wbGVfaWQgPC0gTkEKfSBlbHNlIHsKICBzYW1wbGVfaWQgPC0gbWV0YWRhdGEoZmlsdGVyZWRfc2NlKSRzYW1wbGVfaWQKfQoKIyBhZGQgY2VsbCBzdGF0cyBpZiBtaXNzaW5nCmlmIChpcy5udWxsKHVuZmlsdGVyZWRfc2NlJHN1bSkpIHsKICB1bmZpbHRlcmVkX3NjZSA8LSBzY3V0dGxlOjphZGRQZXJDZWxsUUNNZXRyaWNzKHVuZmlsdGVyZWRfc2NlKQp9CmlmIChpcy5udWxsKGZpbHRlcmVkX3NjZSRzdW0pKSB7CiAgZmlsdGVyZWRfc2NlIDwtIHNjdXR0bGU6OmFkZFBlckNlbGxRQ01ldHJpY3MoZmlsdGVyZWRfc2NlKQp9CmlmIChpcy5udWxsKGZpbHRlcmVkX3NjZSRzdWJzZXRzX21pdG9fcGVyY2VudCkpIHsKICBmaWx0ZXJlZF9zY2Ukc3Vic2V0c19taXRvX3BlcmNlbnQgPC0gTkFfcmVhbF8KICBza2lwX21pUUMgPC0gVFJVRQp9IGVsc2UgewogIHNraXBfbWlRQyA8LSBGQUxTRQp9CgojIHRyeSB0byBhZGQgbWlRQyBpZiBpdCBpcyBtaXNzaW5nCmlmIChpcy5udWxsKG1ldGFkYXRhKGZpbHRlcmVkX3NjZSkkbWlRQ19tb2RlbCkgJiYgIXNraXBfbWlRQykgewogIGZpbHRlcmVkX3NjZSA8LSBzY3BjYVRvb2xzOjphZGRfbWlRQyhmaWx0ZXJlZF9zY2UpCn0KCiMjIENoZWNrIGZvciBhZGRpdGlvbmFsIG1vZGFsaXRpZXMKbW9kYWxpdGllcyA8LSBjKCJSTkEtc2VxIikKCmhhc19hZHQgPC0gImFkdCIgJWluJSBhbHRFeHBOYW1lcyhmaWx0ZXJlZF9zY2UpCmlmIChoYXNfYWR0KSB7CiAgbW9kYWxpdGllcyA8LSBjKG1vZGFsaXRpZXMsICJBRFQiKQp9CgojIGNoZWNrIGZvciBjZWxsaGFzaCB0byBhZGQgdG8gbGlzdCBvZiBtb2RhbGl0aWVzCmhhc19jZWxsaGFzaCA8LSAiY2VsbGhhc2giICVpbiUgYWx0RXhwTmFtZXMoZmlsdGVyZWRfc2NlKQppZiAoaGFzX2NlbGxoYXNoKSB7CiAgbW9kYWxpdGllcyA8LSBjKG1vZGFsaXRpZXMsICJNdWx0aXBsZXgiKQp9CgojIGNoZWNrIGZvciB1bWFwIGFuZCBjZWxsdHlwZXMsIGJ1dCBuZWVkIHRvIGJlIHN1cmUgdGhhdCBwcm9jZXNzZWRfc2NlIGV4aXN0cyBmaXJzdAppZiAoaGFzX3Byb2Nlc3NlZCkgewogIGhhc191bWFwIDwtICJVTUFQIiAlaW4lIHJlZHVjZWREaW1OYW1lcyhwcm9jZXNzZWRfc2NlKQogIGhhc19jbHVzdGVycyA8LSAiY2x1c3RlciIgJWluJSBuYW1lcyhjb2xEYXRhKHByb2Nlc3NlZF9zY2UpKQogIGhhc19zaW5nbGVyIDwtICJzaW5nbGVyIiAlaW4lIG1ldGFkYXRhKHByb2Nlc3NlZF9zY2UpJGNlbGx0eXBlX21ldGhvZHMKICBoYXNfY2VsbGFzc2lnbiA8LSAiY2VsbGFzc2lnbiIgJWluJSBtZXRhZGF0YShwcm9jZXNzZWRfc2NlKSRjZWxsdHlwZV9tZXRob2RzCiAgaGFzX3N1Ym1pdHRlciA8LSAic3VibWl0dGVyIiAlaW4lIG1ldGFkYXRhKHByb2Nlc3NlZF9zY2UpJGNlbGx0eXBlX21ldGhvZHMgJiYKICAgICFhbGwoaXMubmEocHJvY2Vzc2VkX3NjZSRzdWJtaXR0ZXJfY2VsbHR5cGVfYW5ub3RhdGlvbikpICMgbWFrZSBzdXJlIHRoZXkgYXJlbid0IGFsbCBOQQoKICAjIElmIGF0IGxlYXN0IDEgaXMgcHJlc2VudCwgd2UgaGF2ZSBjZWxsIHR5cGUgYW5ub3RhdGlvbnMuCiAgaGFzX2NlbGx0eXBlcyA8LSBhbnkoaGFzX3NpbmdsZXIsIGhhc19jZWxsYXNzaWduLCBoYXNfc3VibWl0dGVyKQoKICBpc19zdXBwbGVtZW50YWwgPC0gRkFMU0UgIyB0aGlzIGlzIG5vdCB0aGUgY2VsbHR5cGUgc3VwcCByZXBvcnQKfSBlbHNlIHsKICBoYXNfdW1hcCA8LSBGQUxTRQogIGhhc19jbHVzdGVycyA8LSBGQUxTRQogIGhhc19zaW5nbGVyIDwtIEZBTFNFCiAgaGFzX2NlbGxhc3NpZ24gPC0gRkFMU0UKICBoYXNfc3VibWl0dGVyIDwtIEZBTFNFCiAgaGFzX2NlbGx0eXBlcyA8LSBGQUxTRQp9CgojIGNoZWNrIGZvciBjZWxsdHlwZXNfcmVwb3J0IGlmIGNlbGx0eXBlcyBhcmUgcHJlc2VudAppZiAoKGhhc19zaW5nbGVyIHwgaGFzX2NlbGxhc3NpZ24pICYgaXMubnVsbChwYXJhbXMkY2VsbHR5cGVfcmVwb3J0KSkgewogIHN0b3AoIkNlbGwgdHlwZSBhbm5vdGF0aW9ucyB3ZXJlIHByb3ZpZGVkIGJ1dCB0aGUgcGFyYW1ldGVyIHNwZWNpZnlpbmcgdGhlIGNlbGwgdHlwZSByZXBvcnQgZmlsZSBpcyBtaXNzaW5nLiIpCn0KCiMgY2hlY2sgaWYgd2UgaGF2ZSBtdWx0aXBsZXgKaGFzX211bHRpcGxleCA8LSBsZW5ndGgoc2FtcGxlX2lkKSA+IDEKc2FtcGxlX3R5cGVzIDwtIG1ldGFkYXRhKHVuZmlsdGVyZWRfc2NlKSRzYW1wbGVfdHlwZQpgYGAKCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CiMgb25seSBwcmludCBvdXQgaW5mbyBib3ggaWYgeGVub2dyYWZ0IG9yIGNlbGwgbGluZSwgd2l0aCBkaWZmZXJlbnQgbG9naWMvd2FybmluZ3MKIyBmb3IgbXVsdGlwbGV4IGxpYnJhcmllcwppZiAoInBhdGllbnQtZGVyaXZlZCB4ZW5vZ3JhZnQiICVpbiUgc2FtcGxlX3R5cGVzKSB7CiAgIyBkZXRlcm1pbmUgd2hpY2ggc2FtcGxlcyBhcmUgdGhlIFBEWHMKICBpZiAoaGFzX211bHRpcGxleCkgewogICAgIyBnZXQgYSBsaXN0IG9mIHNhbXBsZXMgaW4gdGhlIGxpYnJhcnkgdGhhdCBhcmUgcGR4cwogICAgcGR4X3NhbXBsZXMgPC0gbmFtZXMoc2FtcGxlX3R5cGVzW3NhbXBsZV90eXBlcyA9PSAicGF0aWVudC1kZXJpdmVkIHhlbm9ncmFmdCJdKQogICAgcGR4X3NhbXBsZXNfYnVsbGV0cyA8LSBwYXN0ZTAoIjxsaT4iLCBwYXN0ZShwZHhfc2FtcGxlcywgY29sbGFwc2UgPSAiPC9saT48bGk+IiwgIjwvbGk+IikpCgogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1pbmZvXCI+CgogICAgICBUaGlzIGxpYnJhcnkgaW5jbHVkZXMgcGF0aWVudC1kZXJpdmVkIHhlbm9ncmFmdCBzYW1wbGVzLgogICAgICBUaGUgZm9sbG93aW5nIHNhbXBsZXMgYXJlIGRlcml2ZWQgZnJvbSBwYXRpZW50IHhlbm9ncmFmdHM6CgogICAgICB7cGR4X3NhbXBsZXNfYnVsbGV0c30KCiAgICAgIDwvZGl2PgogICAgIikKICB9IGVsc2UgewogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1pbmZvXCI+CgogICAgICBUaGlzIGxpYnJhcnkgY29tZXMgZnJvbSBhIHBhdGllbnQtZGVyaXZlZCB4ZW5vZ3JhZnQgc2FtcGxlLgoKICAgICAgPC9kaXY+CiAgICAiKQogIH0KfQoKaWYgKCJjZWxsIGxpbmUiICVpbiUgc2FtcGxlX3R5cGVzKSB7CiAgaWYgKGhhc19tdWx0aXBsZXgpIHsKICAgICMgZ2V0IGEgbGlzdCBvZiBzYW1wbGVzIGluIHRoZSBsaWJyYXJ5IHRoYXQgYXJlIGNlbGwgbGluZXMKICAgIGNlbGxfbGluZV9zYW1wbGVzIDwtIG5hbWVzKHNhbXBsZV90eXBlc1tzYW1wbGVfdHlwZXMgPT0gImNlbGwgbGluZSJdKQogICAgY2VsbF9saW5lX3NhbXBsZXNfYnVsbGV0cyA8LSBwYXN0ZTAoIjxsaT4iLCBwYXN0ZShjZWxsX2xpbmVfc2FtcGxlcywgY29sbGFwc2UgPSAiPC9saT48bGk+IiwgIjwvbGk+IikpCgogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1pbmZvXCI+CgogICAgICBUaGlzIGxpYnJhcnkgaW5jbHVkZXMgY2VsbCBsaW5lIHNhbXBsZXMuCiAgICAgIFBsZWFzZSBiZSBhd2FyZSB0aGF0IG5vIGNlbGwgdHlwZSBhbm5vdGF0aW9uIGlzIHBlcmZvcm1lZCBmb3IgY2VsbCBsaW5lIHNhbXBsZXMuCiAgICAgIFRoZSBmb2xsb3dpbmcgc2FtcGxlcyBhcmUgZGVyaXZlZCBmcm9tIGNlbGwgbGluZXM6CgogICAgICB7Y2VsbF9saW5lX3NhbXBsZXNfYnVsbGV0c30KCiAgICAgIDwvZGl2PgogICAgIikKICB9IGVsc2UgewogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1pbmZvXCI+CgogICAgICBUaGlzIGxpYnJhcnkgY29tZXMgZnJvbSBhIGNlbGwgbGluZSBzYW1wbGUuCiAgICAgIFBsZWFzZSBiZSBhd2FyZSB0aGF0IG5vIGNlbGwgdHlwZSBhbm5vdGF0aW9uIGlzIHBlcmZvcm1lZCBmb3IgY2VsbCBsaW5lIHNhbXBsZXMuCgogICAgICA8L2Rpdj4KICAgICIpCiAgfQp9CmBgYAoKIyBNZXRhZGF0YSBhbmQgUHJvY2Vzc2luZyBJbmZvcm1hdGlvbiBmb3IgYHIgbGlicmFyeV9pZGAKCmBgYHtyLCBldmFsID0gaGFzX211bHRpcGxleCwgcmVzdWx0cz0nYXNpcyd9CiMgY29udmVydCBzYW1wbGUgaWQgdG8gYnVsbGV0IHNlcGFyYXRlZCBsaXN0Cm11bHRpcGxleF9zYW1wbGVzIDwtIHBhc3RlMCgiPGxpPiIsIHBhc3RlKHNhbXBsZV9pZCwgY29sbGFwc2UgPSAiPC9saT48bGk+IiwgIjwvbGk+IikpCmdsdWU6OmdsdWUoIgogIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC13YXJuaW5nXCI+CgogIFRoaXMgbGlicmFyeSBpcyBtdWx0aXBsZXhlZCBhbmQgY29udGFpbnMgZGF0YSBmcm9tIG1vcmUgdGhhbiBvbmUgc2FtcGxlLgogIERhdGEgZnJvbSB0aGUgZm9sbG93aW5nIHNhbXBsZXMgYXJlIGluY2x1ZGVkIGluIHRoaXMgbGlicmFyeToKCiAge211bHRpcGxleF9zYW1wbGVzfQoKICA8L2Rpdj4KIikKYGBgCgojIyBTYW1wbGUgTWV0YWRhdGEKClRoZSBiZWxvdyB0YWJsZSBzdW1tYXJpemVzIGNsaW5pY2FsIG1ldGFkYXRhIGZvciB0aGUgc2FtcGxlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGxpYnJhcnkuIApCbHVlIGh5cGVybGlua3MgYXJlIHByZXNlbnQgZm9yIGFueSB0ZXJtcyB3aXRoIGFuIG9udG9sb2d5IHRlcm0gaWRlbnRpZmllciBhc3NvY2lhdGVkIHdpdGggdGhlIGRpc3BsYXllZCBodW1hbiByZWFkYWJsZSB2YWx1ZS4gClRoZXNlIGxpbmtzIHdpbGwgZGlyZWN0IHlvdSB0byBhIHdlYiBwYWdlIHdpdGggaW5mb3JtYXRpb24gYWJvdXQgdGhhdCBvbnRvbG9neSB0ZXJtIGlkZW50aWZpZXIuICAKCmBgYHtyfQojIGV4dHJhY3Qgc2NlIG1ldGFkYXRhIGNvbnRhaW5pbmcgcHJvY2Vzc2luZyBpbmZvcm1hdGlvbiBhcyB0YWJsZQp1bmZpbHRlcmVkX21ldGEgPC0gbWV0YWRhdGEodW5maWx0ZXJlZF9zY2UpCgojIGlmIGRhdGEgaXMgbm90IG11bHRpcGxleGVkLCBwcmludCBvdXQgc2FtcGxlIG1ldGFkYXRhCmlmICghaGFzX211bHRpcGxleCkgewogIHByaW50X3NhbXBsZV9tZXRhZGF0YSh1bmZpbHRlcmVkX21ldGEpCn0gZWxzZSB7CiAgIyBvdGhlcndpc2UgcHJpbnQgb3V0IGFuIGluZm8gYm94IHRoYXQgbm8gc2FtcGxlIG1ldGFkYXRhIHdpbGwgYmUgZGlzcGxheWVkCiAga25pdHI6OmFzaXNfb3V0cHV0KAogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC1pbmZvXCI+CgogICAgICBUaGlzIGxpYnJhcnkgaXMgbXVsdGlwbGV4ZWQgYW5kIGNvbnRhaW5zIGRhdGEgZnJvbSBtb3JlIHRoYW4gb25lIHNhbXBsZS4KICAgICAgRGVtdWx0aXBsZXhpbmcgaGFzIG5vdCBiZWVuIHBlcmZvcm1lZCwgc28gc2FtcGxlIG1ldGFkYXRhIHdpbGwgbm90IGJlIGRpc3BsYXllZC4KICAgICAgPC9kaXY+CiAgICAiKQogICkKfQpgYGAKCiMjIFJhdyBMaWJyYXJ5IE1ldHJpY3MKCmBgYHtyIH0KIyBleHRyYWN0IHNjZSBtZXRhZGF0YSBjb250YWluaW5nIHByb2Nlc3NpbmcgaW5mb3JtYXRpb24gYXMgdGFibGUKdW5maWx0ZXJlZF9tZXRhIDwtIG1ldGFkYXRhKHVuZmlsdGVyZWRfc2NlKQoKbGlicmFyeV9pbmZvcm1hdGlvbiA8LSB0aWJibGU6OnRpYmJsZSgKICAiTGlicmFyeSBpZCIgPSBsaWJyYXJ5X2lkLAogICJTYW1wbGUgaWQiID0gcGFzdGUoc2FtcGxlX2lkLCBjb2xsYXBzZSA9ICIsICIpLAogICJUZWNoIHZlcnNpb24iID0gZm9ybWF0KHVuZmlsdGVyZWRfbWV0YSR0ZWNoX3ZlcnNpb24pLCAjIGZvcm1hdCB0byBrZWVwIG51bGxzCiAgIkRhdGEgbW9kYWxpdGllcyIgPSBwYXN0ZShtb2RhbGl0aWVzLCBjb2xsYXBzZSA9ICIsICIpLAogICJDZWxscyByZXBvcnRlZCBieSBhbGV2aW4tZnJ5IiA9CiAgICBmb3JtYXQodW5maWx0ZXJlZF9tZXRhJGFmX251bV9jZWxscywgYmlnLm1hcmsgPSAiLCIsIHNjaWVudGlmaWMgPSBGQUxTRSksCiAgIk51bWJlciBvZiBnZW5lcyBhc3NheWVkIiA9CiAgICBmb3JtYXQobnJvdyh1bmZpbHRlcmVkX3NjZSksIGJpZy5tYXJrID0gIiwiLCBzY2llbnRpZmljID0gRkFMU0UpLAogICJOdW1iZXIgb2YgUk5BLXNlcSByZWFkcyBzZXF1ZW5jZWQiID0KICAgIGZvcm1hdCh1bmZpbHRlcmVkX21ldGEkdG90YWxfcmVhZHMsIGJpZy5tYXJrID0gIiwiLCBzY2llbnRpZmljID0gRkFMU0UpLAogICJQZXJjZW50IG9mIFJOQS1zZXEgcmVhZHMgbWFwcGVkIHRvIHRyYW5zY3JpcHRzIiA9CiAgICBwYXN0ZTAocm91bmQoKHVuZmlsdGVyZWRfbWV0YSRtYXBwZWRfcmVhZHMgLyB1bmZpbHRlcmVkX21ldGEkdG90YWxfcmVhZHMpICogMTAwLCAyKSwgIiUiKQopCgppZiAoaGFzX2FkdCkgewogIGFkdF9leHAgPC0gYWx0RXhwKGZpbHRlcmVkX3NjZSwgImFkdCIpICMgbXVzdCBiZSBmaWx0ZXJlZF9zY2UgaW4gY2FzZSBoYXNfcHJvY2Vzc2VkIGlzIEZBTFNFCiAgYWR0X21ldGEgPC0gbWV0YWRhdGEoYWR0X2V4cCkKCiAgbGlicmFyeV9pbmZvcm1hdGlvbiA8LSBsaWJyYXJ5X2luZm9ybWF0aW9uIHw+CiAgICBtdXRhdGUoCiAgICAgICJOdW1iZXIgb2YgYW50aWJvZGllcyBhc3NheWVkIiA9CiAgICAgICAgZm9ybWF0KG5yb3coYWR0X2V4cCksIGJpZy5tYXJrID0gIiwiLCBzY2llbnRpZmljID0gRkFMU0UpLAogICAgICAiTnVtYmVyIG9mIEFEVCByZWFkcyBzZXF1ZW5jZWQiID0KICAgICAgICBmb3JtYXQoYWR0X21ldGEkdG90YWxfcmVhZHMsIGJpZy5tYXJrID0gIiwiLCBzY2llbnRpZmljID0gRkFMU0UpLAogICAgICAiUGVyY2VudCBvZiBBRFQgcmVhZHMgbWFwcGVkIHRvIEFEVHMiID0KICAgICAgICBwYXN0ZTAocm91bmQoYWR0X21ldGEkbWFwcGVkX3JlYWRzIC8gYWR0X21ldGEkdG90YWxfcmVhZHMgKiAxMDAsIGRpZ2l0cyA9IDIpLCAiJSIpCiAgICApCn0KCmlmIChoYXNfY2VsbGhhc2gpIHsKICBtdWx0aXBsZXhfZXhwIDwtIGFsdEV4cChmaWx0ZXJlZF9zY2UsICJjZWxsaGFzaCIpCiAgbXVsdGlwbGV4X21ldGEgPC0gbWV0YWRhdGEobXVsdGlwbGV4X2V4cCkKCiAgbGlicmFyeV9pbmZvcm1hdGlvbiA8LSBsaWJyYXJ5X2luZm9ybWF0aW9uIHw+CiAgICBtdXRhdGUoCiAgICAgICJOdW1iZXIgb2YgSFRPcyBhc3NheWVkIiA9CiAgICAgICAgZm9ybWF0KG5yb3cobXVsdGlwbGV4X2V4cCksIGJpZy5tYXJrID0gIiwiLCBzY2llbnRpZmljID0gRkFMU0UpLAogICAgICAiTnVtYmVyIG9mIGNlbGxoYXNoIHJlYWRzIHNlcXVlbmNlZCIgPQogICAgICAgIGZvcm1hdChtdWx0aXBsZXhfbWV0YSR0b3RhbF9yZWFkcywgYmlnLm1hcmsgPSAiLCIsIHNjaWVudGlmaWMgPSBGQUxTRSksCiAgICAgICJQZXJjZW50IG9mIGNlbGxoYXNoIHJlYWRzIG1hcHBlZCB0byBIVE9zIiA9CiAgICAgICAgcGFzdGUwKHJvdW5kKG11bHRpcGxleF9tZXRhJG1hcHBlZF9yZWFkcyAvIG11bHRpcGxleF9tZXRhJHRvdGFsX3JlYWRzICogMTAwLCBkaWdpdHMgPSAyKSwgIiUiKQogICAgKQp9CgpsaWJyYXJ5X2luZm9ybWF0aW9uIDwtIGxpYnJhcnlfaW5mb3JtYXRpb24gfD4KICByZWZvcm1hdF9udWxscygpIHw+CiAgdCgpCgojIG1ha2UgdGFibGUgd2l0aCBzYW1wbGUgaW5mb3JtYXRpb24Ka25pdHI6OmthYmxlKGxpYnJhcnlfaW5mb3JtYXRpb24sIGFsaWduID0gInIiKSB8PgogIGthYmxlRXh0cmE6OmthYmxlX3N0eWxpbmcoCiAgICBib290c3RyYXBfb3B0aW9ucyA9ICJzdHJpcGVkIiwKICAgIGZ1bGxfd2lkdGggPSBGQUxTRSwKICAgIHBvc2l0aW9uID0gImxlZnQiCiAgKSB8PgogIGthYmxlRXh0cmE6OmNvbHVtbl9zcGVjKDIsIG1vbm9zcGFjZSA9IFRSVUUpCmBgYAoKIyMgUHJlLVByb2Nlc3NpbmcgSW5mb3JtYXRpb24KCmBgYHtyIH0KIyBkZWZpbmUgdHJhbnNjcmlwdCB0eXBlCnRyYW5zY3JpcHRfdHlwZSA8LSBwYXN0ZSh1bmZpbHRlcmVkX21ldGEkdHJhbnNjcmlwdF90eXBlLCBjb2xsYXBzZSA9ICIgIikKCnByb2Nlc3NpbmdfaW5mbyA8LSB0aWJibGU6OnRpYmJsZSgKICAiU2FsbW9uIHZlcnNpb24iID0gZm9ybWF0KHVuZmlsdGVyZWRfbWV0YSRzYWxtb25fdmVyc2lvbiksCiAgIkFsZXZpbi1mcnkgdmVyc2lvbiIgPSBmb3JtYXQodW5maWx0ZXJlZF9tZXRhJGFsZXZpbmZyeV92ZXJzaW9uKSwKICAiVHJhbnNjcmlwdG9tZSBpbmRleCIgPSBmb3JtYXQodW5maWx0ZXJlZF9tZXRhJHJlZmVyZW5jZV9pbmRleCksCiAgIkFsZXZpbi1mcnkgZHJvcGxldCBkZXRlY3Rpb24iID0gZm9ybWF0KHVuZmlsdGVyZWRfbWV0YSRhZl9wZXJtaXRfdHlwZSksCiAgIlJlc29sdXRpb24iID0gZm9ybWF0KHVuZmlsdGVyZWRfbWV0YSRhZl9yZXNvbHV0aW9uKSwKICAiVHJhbnNjcmlwdHMgaW5jbHVkZWQiID0gZHBseXI6OmNhc2Vfd2hlbigKICAgIHRyYW5zY3JpcHRfdHlwZSA9PSAidG90YWwgc3BsaWNlZCIgfiAiVG90YWwgYW5kIHNwbGljZWQgb25seSIsCiAgICB0cmFuc2NyaXB0X3R5cGUgPT0gInNwbGljZWQiIH4gIlNwbGljZWQgb25seSIsCiAgICBUUlVFIH4gdHJhbnNjcmlwdF90eXBlCiAgKQopIHw+CiAgcmVmb3JtYXRfbnVsbHMoKSB8PgogIHQoKQoKCiMgbWFrZSB0YWJsZSB3aXRoIHByb2Nlc3NpbmcgaW5mb3JtYXRpb24Ka25pdHI6OmthYmxlKHByb2Nlc3NpbmdfaW5mbywgYWxpZ24gPSAiciIpIHw+CiAga2FibGVFeHRyYTo6a2FibGVfc3R5bGluZygKICAgIGJvb3RzdHJhcF9vcHRpb25zID0gInN0cmlwZWQiLAogICAgZnVsbF93aWR0aCA9IEZBTFNFLAogICAgcG9zaXRpb24gPSAibGVmdCIKICApIHw+CiAga2FibGVFeHRyYTo6Y29sdW1uX3NwZWMoMiwgbW9ub3NwYWNlID0gVFJVRSkKYGBgCgojIFJOQS1zZXEgRXhwZXJpbWVudCBTdW1tYXJ5CgojIyBDZWxsIFN0YXRpc3RpY3MKCmBgYHtyfQpiYXNpY19zdGF0aXN0aWNzIDwtIHRpYmJsZTo6dGliYmxlKAogICJNZXRob2QgdXNlZCB0byBmaWx0ZXIgZW1wdHkgZHJvcGxldHMiICAgICAgICAgID0gbWV0YWRhdGEoZmlsdGVyZWRfc2NlKSRmaWx0ZXJpbmdfbWV0aG9kLAogICJOdW1iZXIgb2YgY2VsbHMgcG9zdCBmaWx0ZXJpbmcgZW1wdHkgZHJvcGxldHMiID0gZm9ybWF0KG5jb2woZmlsdGVyZWRfc2NlKSwgYmlnLm1hcmsgPSAiLCIpLAogICJQZXJjZW50IG9mIHJlYWRzIGluIGNlbGxzIiAgICAgICAgICAgICAgICAgICAgID0gcGFzdGUwKHJvdW5kKChzdW0oZmlsdGVyZWRfc2NlJHN1bSkgLyBzdW0odW5maWx0ZXJlZF9zY2Ukc3VtKSkgKiAxMDAsIDIpLCAiJSIpLAogICJNZWRpYW4gVU1JIGNvdW50IHBlciBjZWxsIiAgICAgICAgICAgICAgICAgICAgID0gZm9ybWF0KG1lZGlhbihmaWx0ZXJlZF9zY2Ukc3VtKSwgYmlnLm1hcmsgPSAiLCIpLAogICJNZWRpYW4gZ2VuZXMgZGV0ZWN0ZWQgcGVyIGNlbGwiICAgICAgICAgICAgICAgID0gZm9ybWF0KG1lZGlhbihmaWx0ZXJlZF9zY2UkZGV0ZWN0ZWQpLCBiaWcubWFyayA9ICIsIiksCiAgIk1lZGlhbiBwZXJjZW50IHJlYWRzIG1pdG9jaG9uZHJpYWwiICAgICAgICAgICAgPSBwYXN0ZTAocm91bmQobWVkaWFuKGZpbHRlcmVkX3NjZSRzdWJzZXRzX21pdG9fcGVyY2VudCksIDIpLCAiJSIpCikKCiMgaWYgcHJvY2Vzc2VkIHNjZSBleGlzdHMgYWRkIGZpbHRlcmluZyBhbmQgbm9ybWFsaXphdGlvbiB0YWJsZQppZiAoaGFzX3Byb2Nlc3NlZCkgewogIHByb2Nlc3NlZF9tZXRhIDwtIG1ldGFkYXRhKHByb2Nlc3NlZF9zY2UpCgogIGJhc2ljX3N0YXRpc3RpY3MgPC0gYmFzaWNfc3RhdGlzdGljcyB8PgogICAgbXV0YXRlKAogICAgICAiTWV0aG9kIHVzZWQgdG8gZmlsdGVyIGxvdyBxdWFsaXR5IGNlbGxzIiA9IGZvcm1hdChwcm9jZXNzZWRfbWV0YSRzY3BjYV9maWx0ZXJfbWV0aG9kKSwKICAgICAgIkNlbGxzIGFmdGVyIGZpbHRlcmluZyBsb3cgcXVhbGl0eSBjZWxscyIgPSBmb3JtYXQoZGltKHByb2Nlc3NlZF9zY2UpWzJdLCBiaWcubWFyayA9ICIsIiwgc2NpZW50aWZpYyA9IEZBTFNFKSwKICAgICAgIk5vcm1hbGl6YXRpb24gbWV0aG9kIiAgICAgICAgICAgICAgICAgICAgPSBmb3JtYXQocHJvY2Vzc2VkX21ldGEkbm9ybWFsaXphdGlvbiksCiAgICAgICJNaW5pbXVtIGdlbmVzIHBlciBjZWxsIGN1dG9mZiIgICAgICAgICAgID0gZm9ybWF0KHByb2Nlc3NlZF9tZXRhJG1pbl9nZW5lX2N1dG9mZikKICAgICkKICBpZiAocHJvY2Vzc2VkX21ldGEkc2NwY2FfZmlsdGVyX21ldGhvZCA9PSAibWlRQyIpIHsKICAgIGJhc2ljX3N0YXRpc3RpY3MgPC0gYmFzaWNfc3RhdGlzdGljcyB8PgogICAgICBtdXRhdGUoCiAgICAgICAgIlByb2JhYmlsaXR5IG9mIGNvbXByb21pc2VkIGNlbGwgY3V0b2ZmIiA9IGZvcm1hdChwcm9jZXNzZWRfbWV0YSRwcm9iX2NvbXByb21pc2VkX2N1dG9mZiwgYmlnLm1hcmsgPSAiLCIsIHNjaWVudGlmaWMgPSBGQUxTRSkKICAgICAgKQogIH0KfQoKYmFzaWNfc3RhdGlzdGljcyA8LSBiYXNpY19zdGF0aXN0aWNzIHw+CiAgcmVmb3JtYXRfbnVsbHMoKSB8PiAjIHJlZm9ybWF0IG51bGxzCiAgdCgpCgojIG1ha2UgdGFibGUgd2l0aCBiYXNpYyBzdGF0aXN0aWNzCmtuaXRyOjprYWJsZShiYXNpY19zdGF0aXN0aWNzLCBhbGlnbiA9ICJyIikgfD4KICBrYWJsZUV4dHJhOjprYWJsZV9zdHlsaW5nKAogICAgYm9vdHN0cmFwX29wdGlvbnMgPSAic3RyaXBlZCIsCiAgICBmdWxsX3dpZHRoID0gRkFMU0UsCiAgICBwb3NpdGlvbiA9ICJsZWZ0IgogICkgfD4KICBrYWJsZUV4dHJhOjpjb2x1bW5fc3BlYygyLCBtb25vc3BhY2UgPSBUUlVFKQpgYGAKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KaWYgKAogIGhhc19maWx0ZXJlZCAmJgogICAgKG1ldGFkYXRhKGZpbHRlcmVkX3NjZSkkZmlsdGVyaW5nX21ldGhvZCA9PSAiVU1JIGN1dG9mZiIpCikgewogIGdsdWU6OmdsdWUoIgogICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXdhcm5pbmdcIj4KCiAgICBUaGlzIGxpYnJhcnkgbWF5IGNvbnRhaW4gYSBsb3cgbnVtYmVyIG9mIGNlbGxzIGFuZCB3YXMgdW5hYmxlIHRvIGJlIGZpbHRlcmVkIHVzaW5nIGBEcm9wbGV0VXRpbHNgLgogICAgRHJvcGxldHMgd2l0aCBhIHRvdGFsIFVNSSBjb3VudCDiiaUge21ldGFkYXRhKGZpbHRlcmVkX3NjZSkkdW1pX2N1dG9mZn0gYXJlIGluY2x1ZGVkIGluIHRoZSBmaWx0ZXJlZCBgU2luZ2xlQ2VsbEV4cGVyaW1lbnRgIG9iamVjdC4KCiAgICA8L2Rpdj4KICAiKQp9CmBgYAoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQojIGNoZWNrIGZvciBudW1iZXIgb2YgZmlsdGVyZWQgY2VsbHMKbWluX2ZpbHRlcmVkIDwtIDEwMAppZiAoaGFzX2ZpbHRlcmVkKSB7CiAgaWYgKG5jb2woZmlsdGVyZWRfc2NlKSA8IG1pbl9maWx0ZXJlZCkgewogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC13YXJuaW5nXCI+CgogICAgICBUaGlzIGxpYnJhcnkgY29udGFpbnMgZmV3ZXIgdGhhbiB7bWluX2ZpbHRlcmVkfSBjZWxscyBpbiB0aGUgZmlsdGVyZWQgYFNpbmdsZUNlbGxFeHBlcmltZW50YCBvYmplY3QuCiAgICAgIFRoaXMgbWF5IGFmZmVjdCB0aGUgaW50ZXJwcmV0YXRpb24gb2YgcmVzdWx0cy4KCiAgICAgIDwvZGl2PgogICAgIikKICB9Cn0KCiMgY2hlY2sgZm9yIG51bWJlciBvZiBjZWxscyBwb3N0IHByb2Nlc3NpbmcKbWluX3Byb2Nlc3NlZCA8LSA1MAppZiAoaGFzX3Byb2Nlc3NlZCkgewogIGlmIChuY29sKHByb2Nlc3NlZF9zY2UpIDwgbWluX3Byb2Nlc3NlZCkgewogICAgZ2x1ZTo6Z2x1ZSgiCiAgICAgIDxkaXYgY2xhc3M9XCJhbGVydCBhbGVydC13YXJuaW5nXCI+CgogICAgICBUaGlzIGxpYnJhcnkgY29udGFpbnMgZmV3ZXIgdGhhbiB7bWluX3Byb2Nlc3NlZH0gY2VsbHMgaW4gdGhlIHByb2Nlc3NlZCBgU2luZ2xlQ2VsbEV4cGVyaW1lbnRgIG9iamVjdCBhZnRlciByZW1vdmFsIG9mIGxvdyBxdWFsaXR5IGNlbGxzLgogICAgICBVTUFQIGlzIHVuYWJsZSB0byBiZSBjYWxjdWxhdGVkIGFuZCBwbG90cyB3aWxsIG5vdCBiZSBzaG93bi4KCiAgICAgIDwvZGl2PgogICAgIikKICB9Cn0KYGBgCgojIyBLbmVlIFBsb3QKCmBgYHtyLCBmaWcuYWx0PSJTbW9vdGhlZCBrbmVlIHBsb3Qgb2YgZmlsdGVyZWQgYW5kIHVuZmlsdGVyZWQgZHJvcGxldHMifQp1bmZpbHRlcmVkX2NlbGxkYXRhIDwtIGRhdGEuZnJhbWUoY29sRGF0YSh1bmZpbHRlcmVkX3NjZSkpIHw+CiAgbXV0YXRlKAogICAgcmFuayA9IHJhbmsoLXVuZmlsdGVyZWRfc2NlJHN1bSwgdGllcy5tZXRob2QgPSAiZmlyc3QiKSwgIyB1c2luZyBmdWxsIHNwZWMgZm9yIGNsYXJpdHkKICAgIGZpbHRlcl9wYXNzID0gY29sbmFtZXModW5maWx0ZXJlZF9zY2UpICVpbiUgY29sbmFtZXMoZmlsdGVyZWRfc2NlKQogICkgfD4KICBzZWxlY3Qoc3VtLCByYW5rLCBmaWx0ZXJfcGFzcykgfD4KICBmaWx0ZXIoc3VtID4gMCkgIyByZW1vdmUgemVyb3MgZm9yIHBsb3R0aW5nCgoKZ3JvdXBlZF9jZWxsZGF0YSA8LSB1bmZpbHRlcmVkX2NlbGxkYXRhIHw+CiAgbXV0YXRlKHJhbmtfZ3JvdXAgPSBmbG9vcihyYW5rIC8gMTAwKSkgfD4KICBncm91cF9ieShyYW5rX2dyb3VwKSB8PgogIHN1bW1hcml6ZSgKICAgIG1lZF9zdW0gPSBtZWRpYW4oc3VtKSwKICAgIG1lZF9yYW5rID0gbWVkaWFuKHJhbmspLAogICAgcGN0X3Bhc3NlZCA9IHN1bShmaWx0ZXJfcGFzcykgLyBuKCkgKiAxMDAKICApCgp0b3BfY2VsbGRhdGEgPC0gdW5maWx0ZXJlZF9jZWxsZGF0YSB8PgogIGZpbHRlcihyYW5rIDw9IDUwKSB8PgogIG11dGF0ZShmaWx0ZXJfcGN0ID0gaWZlbHNlKGZpbHRlcl9wYXNzLCAxMDAsIDApKQoKZ2dwbG90KGdyb3VwZWRfY2VsbGRhdGEsIGFlcyh4ID0gbWVkX3JhbmssIHkgPSBtZWRfc3VtLCBjb2xvciA9IHBjdF9wYXNzZWQpKSArCiAgZ2VvbV9wb2ludCgKICAgIG1hcHBpbmcgPSBhZXMoeCA9IHJhbmssIHkgPSBzdW0sIGNvbG9yID0gZmlsdGVyX3BjdCksCiAgICBkYXRhID0gdG9wX2NlbGxkYXRhLAogICAgYWxwaGEgPSAwLjUKICApICsKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMiwgbGluZWVuZCA9ICJyb3VuZCIsIGxpbmVqb2luID0gInJvdW5kIikgKwogIHNjYWxlX3hfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX3lfbG9nMTAobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoYWNjdXJhY3kgPSAxKSkgKwogIHNjYWxlX2NvbG9yX2dyYWRpZW50MigKICAgIGxvdyA9ICJncmV5NzAiLAogICAgbWlkID0gImZvcmVzdGdyZWVuIiwKICAgIGhpZ2ggPSAiZGFya2dyZWVuIiwKICAgIG1pZHBvaW50ID0gNTAKICApICsKICBsYWJzKAogICAgeCA9ICJSYW5rIiwKICAgIHkgPSAiVG90YWwgVU1JIGNvdW50IiwKICAgIGNvbG9yID0gIiUgcGFzc2luZ1xuY2VsbCBmaWx0ZXIiCiAgKSArCiAgdGhlbWUoCiAgICBsZWdlbmQucG9zaXRpb24gPSBjKDAsIDApLAogICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDAsIDApLAogICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleTIwIiwgbGluZXdpZHRoID0gMC4yNSksCiAgICBsZWdlbmQuYm94Lm1hcmdpbiA9IG1hcmdpbihyZXAoNSwgNCkpCiAgKQpgYGAKClRoZSB0b3RhbCBVTUkgY291bnQgb2YgZWFjaCBkcm9wbGV0IChiYXJjb2RlKSBwbG90dGVkIGFnYWluc3QgdGhlIHJhbmsgb2YgdGhhdCBkcm9wbGV0IGFsbG93cyB2aXN1YWxpemF0aW9uIG9mIHRoZSBkaXN0cmlidXRpb24gb2Ygc2VxdWVuY2luZyBkZXB0aCBhY3Jvc3MgZHJvcGxldHMuClRoZSBkcm9wbGV0cyB0aGF0IGFyZSBleHBlY3RlZCB0byBjb250YWluIGNlbGxzIHdlcmUgaWRlbnRpZmllZCB3aXRoIFtgRHJvcGxldFV0aWxzOjplbXB0eURyb3BzQ2VsbFJhbmdlcigpYF0oaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL3BhY2thZ2VzL3JlbGVhc2UvYmlvYy9odG1sL0Ryb3BsZXRVdGlscy5odG1sKSwgdW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQgaW4gdGhlIGBDZWxsIFN0YXRpc3RpY3NgIHRhYmxlLCB3aGljaCB1c2VzIGJvdGggdGhlIHRvdGFsIFVNSSBjb3VudHMgYW5kIGV4cHJlc3NlZCBnZW5lIGNvbnRlbnQgKGFkYXB0ZWQgZnJvbSBbTHVuICBfZXQgYWwuXyAyMDE5XShodHRwczovL2RvaS5vcmcvMTAuMTE4Ni9zMTMwNTktMDE5LTE2NjIteSkpLgpBcyB0aGUgYm91bmRhcnkgYmV0d2VlbiBkcm9wbGV0cyBwYXNzaW5nIGFuZCBmYWlsaW5nIHRoaXMgZmlsdGVyIGlzIG5vdCBzb2xlbHkgZGVwZW5kZW50IG9uIHRvdGFsIFVNSSBjb3VudCwgc29tZSByZWdpb25zIGNvbnRhaW4gZHJvcGxldHMgaW4gYm90aCBjYXRlZ29yaWVzLgpUaGUgY29sb3IgaW4gdGhpcyBwbG90IGluZGljYXRlcyB0aGUgcGVyY2VudGFnZSBvZiBkcm9wbGV0cyBpbiBhIHJlZ2lvbiBwYXNzaW5nIHRoZSBmaWx0ZXIuCgojIyBDZWxsIFJlYWQgTWV0cmljcwoKYGBge3IsIGZpZy5hbHQ9IlRvdGFsIFVNSSB4IGdlbmVzIGV4cHJlc3NlZCJ9CmZpbHRlcmVkX2NlbGxkYXRhIDwtIGRhdGEuZnJhbWUoY29sRGF0YShmaWx0ZXJlZF9zY2UpKQoKZ2dwbG90KAogIGZpbHRlcmVkX2NlbGxkYXRhLAogIGFlcygKICAgIHggPSBzdW0sCiAgICB5ID0gZGV0ZWN0ZWQsCiAgICBjb2xvciA9IHN1YnNldHNfbWl0b19wZXJjZW50CiAgKQopICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpc19jKGxpbWl0cyA9IGMoMCwgMTAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmxhYmVsX251bWJlcihhY2N1cmFjeSA9IDEpKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6bGFiZWxfbnVtYmVyKGFjY3VyYWN5ID0gMSkpICsKICBsYWJzKAogICAgeCA9ICJUb3RhbCBVTUkgY291bnQiLAogICAgeSA9ICJOdW1iZXIgb2YgZ2VuZXMgZGV0ZWN0ZWQiLAogICAgY29sb3IgPSAiUGVyY2VudCByZWFkc1xubWl0b2Nob25kcmlhbCIKICApICsKICB0aGVtZSgKICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMCwgMSksCiAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMSksCiAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJncmV5MjAiLCBsaW5ld2lkdGggPSAwLjI1KSwKICAgIGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKHJlcCg1LCA0KSkKICApCmBgYAoKVGhlIGFib3ZlIHBsb3Qgb2YgY2VsbCBtZXRyaWNzIGluY2x1ZGVzIG9ubHkgZHJvcGxldHMgd2hpY2ggaGF2ZSBwYXNzZWQgdGhlIGBlbXB0eURyb3BzQ2VsbFJhbmdlcigpYCBmaWx0ZXIuClRoZSBwbG90IHdpbGwgdXN1YWxseSBkaXNwbGF5IGEgc3Ryb25nIChidXQgY3VydmVkKSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgdG90YWwgVU1JIGNvdW50IGFuZCB0aGUgbnVtYmVyIG9mIGdlbmVzIGRldGVjdGVkLgpDZWxscyB3aXRoIGxvdyBVTUkgY291bnRzIGFuZCBoaWdoIG1pdG9jaG9uZHJpYWwgcGVyY2VudGFnZXMgbWF5IHJlcXVpcmUgZnVydGhlciBmaWx0ZXJpbmcuCgojIyBtaVFDIE1vZGVsIERpYWdub3N0aWNzCgpgYGB7ciwgZmlnLmFsdD0ibWlRQyBtb2RlbCBkaWFnbm9zdGljcyBwbG90IiwgcmVzdWx0cz0nYXNpcycsIHdhcm5pbmc9RkFMU0V9CmlmIChza2lwX21pUUMpIHsKICBjYXQoIm1pUUMgbW9kZWwgbm90IGNyZWF0ZWQsIHNraXBwaW5nIG1pUUMgcGxvdC4gVXN1YWxseSB0aGlzIGlzIGJlY2F1c2UgbWl0b2Nob25kcmlhbCBnZW5lIGRhdGEgd2FzIG5vdCBhdmFpbGFibGUuIikKfSBlbHNlIHsKICAjIHJlbW92ZSBwcm9iX2NvbXByb21pc2VkIGlmIGl0IGV4aXN0cywgYXMgdGhpcyB3aWxsIGNhdXNlIGVycm9ycyB3aXRoIHBsb3RNb2RlbAogIGZpbHRlcmVkX3NjZSRwcm9iX2NvbXByb21pc2VkIDwtIE5VTEwKICBtaVFDX21vZGVsIDwtIG1ldGFkYXRhKGZpbHRlcmVkX3NjZSkkbWlRQ19tb2RlbAoKICBpZiAoaXMubnVsbChtaVFDX21vZGVsKSB8fCBsZW5ndGgobWlRQ19tb2RlbEBjb21wb25lbnRzKSA8IDIpIHsKICAgICMgbW9kZWwgZGlkbid0IGZpdCwganVzdCBwbG90IG1ldHJpY3MKICAgIG1pUUNfcGxvdCA8LSBtaVFDOjpwbG90TWV0cmljcyhmaWx0ZXJlZF9zY2UpCiAgfSBlbHNlIHsKICAgIG1pUUNfcGxvdCA8LSBtaVFDOjpwbG90TW9kZWwoZmlsdGVyZWRfc2NlLCBtb2RlbCA9IG1pUUNfbW9kZWwpCiAgICAjIHNldCBsaW5lIHRoaWNrbmVzcwogICAgbGluZV9hZXMgPC0gbGlzdChsaW5ld2lkdGggPSAxLCBhbHBoYSA9IDAuOCkKICAgIG1pUUNfcGxvdCRsYXllcnNbWzJdXSRhZXNfcGFyYW1zIDwtIGxpbmVfYWVzCiAgICBtaVFDX3Bsb3QkbGF5ZXJzW1szXV0kYWVzX3BhcmFtcyA8LSBsaW5lX2FlcwogIH0KCiAgbWlRQ19wbG90ICsKICAgIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLCAxMDApKSArCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpsYWJlbF9udW1iZXIoYWNjdXJhY3kgPSAxKSkgKwogICAgbGFicygKICAgICAgeCA9ICJOdW1iZXIgb2YgZ2VuZXMgZGV0ZWN0ZWQiLAogICAgICB5ID0gIlBlcmNlbnQgcmVhZHMgbWl0b2Nob25kcmlhbCIKICAgICkgKwogICAgdGhlbWUoCiAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9IGMoMSwgMSksCiAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygxLCAxKSwKICAgICAgbGVnZW5kLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiZ3JleTIwIiwgbGluZXdpZHRoID0gMC4yNSksCiAgICAgIGxlZ2VuZC5ib3gubWFyZ2luID0gbWFyZ2luKHJlcCg1LCA0KSkKICAgICkKfQpgYGAKCldlIGNhbGN1bGF0ZSB0aGUgcHJvYmFiaWxpdHkgdGhhdCBhIGNlbGwgaXMgY29tcHJvbWlzZWQgZHVlIHRvIGRlZ3JhZGF0aW9uIG9yIHJ1cHR1cmUgdXNpbmcgW2BtaVFDYF0oaHR0cHM6Ly9iaW9jb25kdWN0b3Iub3JnL3BhY2thZ2VzL3JlbGVhc2UvYmlvYy9odG1sL21pUUMuaHRtbCkgKFtIaXBwZW4gX2V0IGFsLl8gMjAyMV0oaHR0cHM6Ly9kb2kub3JnLzEwLjEzNzEvam91cm5hbC5wY2JpLjEwMDkyOTApKS4KVGhpcyByZWxpZXMgb24gZml0dGluZyBhIG1peHR1cmUgbW9kZWwgdXNpbmcgdGhlIG51bWJlciBvZiBnZW5lcyBleHByZXNzZWQgYnkgYSBjZWxsIGFuZCB0aGUgcGVyY2VudGFnZSBvZiBtaXRvY2hvbmRyaWFsIHJlYWRzLgpUaGUgZXhwZWN0ZWQgcGxvdCB3aWxsIHNob3cgYSBjaGFyYWN0ZXJpc3RpYyB0cmlhbmd1bGFyIHNoYXBlIGFuZCB0d28gbW9kZWwgZml0IGxpbmVzLgpDZWxscyB3aXRoIGxvdyBudW1iZXJzIG9mIGdlbmVzIGV4cHJlc3NlZCBtYXkgaGF2ZSBib3RoIGxvdyBhbmQgaGlnaCBtaXRvY2hvbmRyaWFsIHBlcmNlbnRhZ2UsIGJ1dCBjZWxscyB3aXRoIG1hbnkgZ2VuZXMgdGVuZCB0byBoYXZlIGEgbG93IG1pdG9jaG9uZHJpYWwgcGVyY2VudGFnZS4KQ29tcHJvbWlzZWQgY2VsbHMgYXJlIGxpa2VseSB0byBoYXZlIGEgZmV3ZXIgZ2VuZXMgZGV0ZWN0ZWQgYW5kIGhpZ2hlciBwZXJjZW50YWdlIG9mIG1pdG9jaG9uZHJpYWwgcmVhZHMuCgpJZiB0aGUgbW9kZWwgaGFzIGZhaWxlZCB0byBmaXQgcHJvcGVybHksIHRoZSBwYXR0ZXJuIG9mIGNlbGxzIG1heSBkaWZmZXIsIGFuZCB0aGVyZSBtYXkgbm90IGJlIG1vZGVsIGZpdCBsaW5lcy4KVGhpcyBjYW4gYmUgdGhlIHJlc3VsdCBvZiBhIGxvdy1xdWFsaXR5IGxpYnJhcnkgb3IgbWF5IG9jY3VyIGlmIHRoZXJlIGlzIG5vIG1pdG9jaG9uZHJpYWwgY29udGVudCwgYXMgaW4gdGhlIGNhc2Ugb2YgYSBoaWdoLXF1YWxpdHkgc2luZ2xlLW51Y2xldXMgc2FtcGxlLgpJbiBzdWNoIHNpdHVhdGlvbnMsIHRoZSBjYWxjdWxhdGVkIHByb2JhYmlsaXR5IG9mIGNvbXByb21pc2UgbWF5IG5vdCBiZSB2YWxpZCAoc2VlIFttaVFDIHZpZ25ldHRlXShodHRwczovL2Jpb2NvbmR1Y3Rvci5vcmcvcGFja2FnZXMvMy4xMy9iaW9jL3ZpZ25ldHRlcy9taVFDL2luc3QvZG9jL21pUUMuaHRtbCN3aGVuLW5vdC10by11c2UtbWlxYykgZm9yIG1vcmUgZGV0YWlscykuCgojIyBSZW1vdmluZyBsb3cgcXVhbGl0eSBjZWxscwoKVGhlIGJlbG93IHBsb3QgaGlnaGxpZ2h0cyBjZWxscyB0aGF0IHdlcmUgcmVtb3ZlZCBwcmlvciB0byBub3JtYWxpemF0aW9uIGFuZCBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24uCkNlbGxzIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQgYmFzZWQgb24gUk5BIGNvdW50cyBhcmUgdGhvc2UgdGhhdCBhcmUgaWRlbnRpZmllZCB0byBiZSBsb3cgcXVhbGl0eSBjZWxscywgc3VjaCBhcyBjZWxscyB3aXRoIGhpZ2ggcHJvYmFiaWxpdHkgb2YgYmVpbmcgY29tcHJvbWlzZWQuClRoZSBtZXRob2Qgb2YgZmlsdGVyaW5nIGlzIGluZGljYXRlZCBhYm92ZSB0aGUgcGxvdCBhcyBlaXRoZXIgYG1pUUNgIG9yIGBNaW5pbXVtIGdlbmUgY3V0b2ZmYC4KSWYgYG1pUUNgLCBjZWxscyBiZWxvdyB0aGUgc3BlY2lmaWVkIHByb2JhYmlsaXR5IGNvbXByb21pc2VkIGN1dG9mZiBhbmQgYWJvdmUgdGhlIG1pbmltdW0gbnVtYmVyIG9mIHVuaXF1ZSBnZW5lcyBpZGVudGlmaWVkIGFyZSBrZXB0IGZvciBkb3duc3RyZWFtIGFuYWx5c2VzLgpJZiBvbmx5IGEgYE1pbmltdW0gZ2VuZSBjdXRvZmZgIGlzIHVzZWQsIHRoZW4gYG1pUUNgIGlzIG5vdCB1c2VkIGFuZCBvbmx5IHRob3NlIGNlbGxzIHRoYXQgcGFzcyB0aGUgbWluaW11bSBudW1iZXIgb2YgdW5pcXVlIGdlbmVzIGlkZW50aWZpZWQgdGhyZXNob2xkIGFyZSByZXRhaW5lZC4KVGhlIGRvdHRlZCB2ZXJ0aWNhbCBsaW5lIGluZGljYXRlcyB0aGUgbWluaW11bSBnZW5lIGN1dG9mZiB1c2VkIGZvciBmaWx0ZXJpbmcuCgoKYGBge3IgcmVzdWx0cz0nYXNpcyd9CmlmIChoYXNfZmlsdGVyZWQgJiYgaGFzX3Byb2Nlc3NlZCkgewogICMgZ3JhYiBjdXRvZmZzIGFuZCBmaWx0ZXJpbmcgbWV0aG9kIGZyb20gcHJvY2Vzc2VkIHNjZQogIG1pbl9nZW5lX2N1dG9mZiA8LSBwcm9jZXNzZWRfbWV0YSRtaW5fZ2VuZV9jdXRvZmYKCiAgZmlsdGVyX21ldGhvZCA8LSBwcm9jZXNzZWRfbWV0YSRzY3BjYV9maWx0ZXJfbWV0aG9kCgogICMgYWRkIGNvbHVtbiB0byBjb2xkYXRhIGxhYmVsaW5nIGNlbGxzIHRvIGtlZXAvcmVtb3ZlIGJhc2VkIG9uIGZpbHRlcmluZyBtZXRob2QKICBmaWx0ZXJlZF9jb2xkYXRhX2RmIDwtIGNvbERhdGEoZmlsdGVyZWRfc2NlKSB8PgogICAgYXMuZGF0YS5mcmFtZSgpIHw+CiAgICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbigiYmFyY29kZSIpCgogIGdncGxvdChmaWx0ZXJlZF9jb2xkYXRhX2RmLCBhZXMoeCA9IGRldGVjdGVkLCB5ID0gc3Vic2V0c19taXRvX3BlcmNlbnQsIGNvbG9yID0gc2NwY2FfZmlsdGVyKSkgKwogICAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSwgc2l6ZSA9IDEpICsKICAgIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IG1pbl9nZW5lX2N1dG9mZiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICAgbGFicygKICAgICAgeCA9ICJOdW1iZXIgb2YgZ2VuZXMgZGV0ZWN0ZWQiLAogICAgICB5ID0gIk1pdG9jaG9uZHJpYWwgcGVyY2VudGFnZSIsCiAgICAgIGNvbG9yID0gIkZpbHRlciIsCiAgICAgIHRpdGxlID0gc3RyaW5ncjo6c3RyX3JlcGxhY2UoZmlsdGVyX21ldGhvZCwgIl8iLCAiICIpCiAgICApICsKICAgIHRoZW1lKAogICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwKICAgICAgbGVnZW5kLnBvc2l0aW9uID0gYygxLCAxKSwKICAgICAgbGVnZW5kLmp1c3RpZmljYXRpb24gPSBjKDEsIDEpLAogICAgICBsZWdlbmQuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJncmV5MjAiLCBsaW5ld2lkdGggPSAwLjI1KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KQogICAgKQp9IGVsc2UgewogIGdsdWU6OmdsdWUoIgogICAgPGRpdiBjbGFzcz1cImFsZXJ0IGFsZXJ0LXdhcm5pbmdcIj4KCiAgICBObyBmaWx0ZXJpbmcgb2YgbG93IHF1YWxpdHkgY2VsbHMgd2FzIHBlcmZvcm1lZCBvbiB0aGlzIGxpYnJhcnkuCgogICAgPC9kaXY+CiAgIikKfQpgYGAKClRoZSByYXcgY291bnRzIGZyb20gYWxsIGNlbGxzIHRoYXQgcmVtYWluIGFmdGVyIGZpbHRlcmluZyBsb3cgcXVhbGl0eSBjZWxscyAoUk5BIG9ubHkpIGFyZSB0aGVuIG5vcm1hbGl6ZWQgcHJpb3IgdG8gc2VsZWN0aW9uIG9mIGhpZ2hseSB2YXJpYWJsZSBnZW5lcyBhbmQgZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLgoKCgo8IS0tIE5leHQgc2VjdGlvbiBpbmNsdWRlIG9ubHkgaWYgVU1BUCBpcyBwcmVzZW50IC0tPgpgYGB7ciwgY2hpbGQ9J3VtYXBfcWMucm1kJywgZXZhbCA9IGhhc191bWFwfQpgYGAKCjwhLS0gTmV4dCBzZWN0aW9uIGluY2x1ZGVkIG9ubHkgaWYgQ0lURS1zZXEgZGF0YSBpcyBwcmVzZW50IC0tPgpgYGB7ciwgY2hpbGQ9J2NpdGVfcWMucm1kJywgZXZhbCA9IGhhc19hZHR9CmBgYAoKPCEtLSBOZXh0IHNlY3Rpb24gb25seSBpbmNsdWRlZCBpZiBtdWx0aXBsZXggZGF0YSBpcyBwcmVzZW50IC0tPgpgYGB7ciwgY2hpbGQ9J211bHRpcGxleF9xYy5ybWQnLCBldmFsID0gaGFzX2NlbGxoYXNofQpgYGAKCjwhLS0gTmV4dCBzZWN0aW9ucyBvbmx5IGluY2x1ZGVkIGlmIGNlbGx0eXBlIGFubm90YXRpb25zIGFyZSBwcmVzZW50IC0tPgpgYGB7ciwgY2hpbGQ9J3V0aWxzL2NlbGx0eXBlX2Z1bmN0aW9ucy5ybWQnLCBldmFsID0gaGFzX2NlbGx0eXBlc30KYGBgCgpgYGB7ciwgY2hpbGQ9J2NlbGx0eXBlc19xYy5ybWQnLCBldmFsID0gaGFzX2NlbGx0eXBlc30KYGBgCgoKIyBTZXNzaW9uIEluZm8KPGRldGFpbHM+CjxzdW1tYXJ5PlIgc2Vzc2lvbiBpbmZvcm1hdGlvbjwvc3VtbWFyeT4KYGBge3Igc2Vzc2lvbl9pbmZvfQppZiAocmVxdWlyZU5hbWVzcGFjZSgic2Vzc2lvbmluZm8iLCBxdWlldGx5ID0gVFJVRSkpIHsKICBzZXNzaW9uaW5mbzo6c2Vzc2lvbl9pbmZvKCkKfSBlbHNlIHsKICBzZXNzaW9uSW5mbygpCn0KYGBgCjwvZGV0YWlscz4K